package com.duckygo.towerdefense.game.sprites;

import java.util.Vector;

import android.util.Log;
import android.view.KeyEvent;

import com.duckygo.towerdefense.game.astar.AStar;
import com.duckygo.towerdefense.game.astar.AStarNode;
import com.duckygo.towerdefense.game.scenes.TowerDefenseScene;

public class Unit extends AnimatedSprite2D {
	
	public static String directions[] = new String[] { "walk_e", "walk_n", "walk_ne", "walk_nw", "walk_s", "walk_se", "walk_sw","walk_w" };

	

	
	private static Vector<AStarNode> parent_path;
	
	private AnimationRunnable animator;
	
	private String direction;

	protected UnitHealth health;

	public UnitHealth getHealth() {
		if (health == null) {
			this.health = new UnitHealth(this, 100);
		}
		
		return health;
	}


	private Vector<AStarNode> path;
	
	
	public Unit() {
		
		anchor = CENTER;
		
		addChild(getHealth());
		
		switchDirection();
		calcPath();
	}
	

	private void calcPath() {
		if (path == null)	{
			if (parent_path == null) parent_path = new AStar(TowerDefenseScene.terrain).solve(new AStarNode(1, 0), new AStarNode(AStar.MAP_WIDTH - 2, AStar.MAP_HEIGHT - 1));
			path = (Vector<AStarNode>) parent_path.clone();
		}
	}
	
	@Override
	public boolean onKeyEvent(KeyEvent event, int keyCode) {
		switch(keyCode) {
		case KeyEvent.KEYCODE_DPAD_UP:
			setDirection("walk_n");
			return true;
			
		case KeyEvent.KEYCODE_DPAD_DOWN:
			setDirection("walk_s");
			return true;

		case KeyEvent.KEYCODE_DPAD_RIGHT:
			setDirection("walk_e");
			return true;

		case KeyEvent.KEYCODE_DPAD_LEFT:
			setDirection("walk_w");
			return true;

		}
		return false;
	}
	
	
	private void setDirection(String direction) {
		if (direction == this.direction) {
			return;
		}
		
		if (animator != null) {
			animator.stop();
		}
		
		//Log.w("Viking", "Direction [" + direction + "]");
		
		this.direction = direction;
		animator = play(direction, true);
	}


	private void switchDirection() {
		setDirection(directions[(int) Math.floor(Math.random() * directions.length)]);
	}
	
	private void updateDirection() {
		if (direction.equals("walk_s")) {
			setY(y + 1);
		}
		if (direction.equals("walk_n")) {
			setY(y - 1);
		}
		if (direction.equals("walk_e")) {
			setX(x + 1);
		}
		if (direction.equals("walk_w")) {
			setX(x - 1);
		}
		if (direction.equals("walk_se")) {
			setY(y + 1);
			setX(x + 1);
		}
		if (direction.equals("walk_ne")) {
			setY(y - 1);
			setX(x + 1);
		}
		if (direction.equals("walk_sw")) {
			setY(y + 1);
			setX(x - 1);
		}
		if (direction.equals("walk_nw")) {
			setY(y - 1);
			setX(x - 1);
		}
	}
	
	
	@Override
	public void update(long time) {
		
		if (health.health <= 0) {
			if (parent != null) parent.removeChild(this);
			return;
		}
		
		
		followPath();
		updateDirection();
		
//		if (Math.random() > 0.99) {
//			switchDirection();
//		}
	}


	private void followPath() {
		if (path == null) {
			return;
		}
		
		AStarNode node = null;
		if (path.size() > 0) 
			node = path.firstElement();
		
		if (node == null) {
			setDirection("stop");
			return;
		}
		
		int pointX = node.x * (((Sprite2D)parent).width /  AStar.MAP_WIDTH);
		int pointY = node.y * (((Sprite2D)parent).height /  AStar.MAP_HEIGHT);
		
		int distX = (int) (pointX - this.x);
		int distY = (int) (pointY - this.y);
		
		if (Math.abs(distX) < 10 && Math.abs(distY) < 10) {
			//Log.w("Viking", "Point [" + node.x + "," + node.y + "]");
			path.remove(0);
		}
		
		if (Math.abs(distX) > Math.abs(distY) + 10) {
			if (distX > 0) {
				setDirection("walk_e");
			} else {
				setDirection("walk_w");
			}
		} else if (Math.abs(distY) > Math.abs(distX) + 10) {
			if (distY > 0) {
				setDirection("walk_s");
			} else {
				setDirection("walk_n");
			}
		} else {
			if (distX > 0 && distY > 0) {
				setDirection("walk_se");
			}
			if (distX > 0 && distY < 0) {
				setDirection("walk_ne");
			}
			if (distX < 0 && distY > 0) {
				setDirection("walk_sw");
			}
			if (distX < 0 && distY < 0) {
				setDirection("walk_nw");
			}
		}

		
	}
	
	
	
}
